package org.wang.generalcode.support.base;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.wang.generalcode.support.utils.BeanUtil;

import javax.validation.constraints.NotEmpty;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

@Validated
public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> implements BaseService<T> {
    public BaseServiceImpl() {
    }

    public boolean save(T entity) {
        this.resolveEntity(entity);
        return super.save(entity);
    }

    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        entityList.forEach(this::resolveEntity);
        return super.saveBatch(entityList, batchSize);
    }

    public boolean updateById(T entity) {
        this.resolveEntity(entity);
        return super.updateById(entity);
    }

    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        entityList.forEach(this::resolveEntity);
        return super.updateBatchById(entityList, batchSize);
    }

    public boolean saveOrUpdate(T entity) {
        return entity.getId() == null ? this.save(entity) : this.updateById(entity);
    }

    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
        entityList.forEach(this::resolveEntity);
        return super.saveOrUpdateBatch(entityList, batchSize);
    }

    @Transactional(
            rollbackFor = {Exception.class}
    )
    public boolean deleteLogic(@NotEmpty List<Long> ids) {
        List<T> list = new ArrayList();
        ids.forEach((id) -> {
            T entity = (T) BeanUtil.newInstance(this.currentModelClass());
            entity.setUpdateTime(DateUtil.date());
            entity.setId(id);
            list.add(entity);
        });
        return super.updateBatchById(list) && super.removeByIds(ids);
    }

    public boolean changeStatus(@NotEmpty List<Long> ids, Integer status) {
        List<T> list = new ArrayList();
        ids.forEach((id) -> {
            T entity = (T) BeanUtil.newInstance(this.currentModelClass());
            entity.setUpdateTime(DateUtil.date());
            entity.setId(id);
//            entity.setStatus(status);
            list.add(entity);
        });
        return super.updateBatchById(list);
    }

    private void resolveEntity(T entity){
        try {
            Date now = DateUtil.date();
            if (entity.getId() == null) {
//                if (entity.getStatus() == null) {
//                    entity.setStatus(1);
//                }

                entity.setCreateTime(now);
            }

            entity.setUpdateTime(now);
//            entity.setIsDeleted(0);
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
    }
}
